<?php
/**
 * Spectus Object Relation Mapper
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 *
 * @category	Spectus
 * @package		Spectus
 * @copyright	Copyright (c) 2008-2009
 * @author		Mient-jan Stelling
 * @license		MIT License  http://en.wikipedia.org/wiki/MIT_License 
 */

require_once 'Exception.php';
require_once 'Zend/Db/Table/Row/Abstract.php';

/**
 * Spectus_Default_Table_Row_Abstract
 *
 * @todo major recode of class 
 * @author Mient-jan Stelling
 **/
abstract class Spectus_Default_Table_Row_Abstract extends Zend_Db_Table_Row_Abstract
{
	protected $_relationRows = array();	
	protected $_relationRowsUsed = array();	

	protected $_childClasses = array();	
	public $_parent = NULL;
	
	/**
	 * Magic getter
	 *
	 * @param unknown_type $argStrName
	 * @return unknown
	 */
	public function __get( $argStrName )
	{
		
		try {
			return parent::__get( $argStrName );
		}
		catch ( Exception $e )
		{
			$arrHasMany = $this->_table->info('hasMany');

			if( array_key_exists( $argStrName, $arrHasMany ) )
			{
				try {
					$this->$argStrName = $this->$argStrName = $this->findDependentRowset( $arrHasMany[ $argStrName ]['refTableClass'] );
				}
				catch(Exception $objE){
					$this->$argStrName = NULL;
				}
				
				return $this->$argStrName;
			}
			else
			{
				$arrReferenceMap = $this->_table->info('referenceMap');

				if( !empty( $arrReferenceMap[ $argStrName ] ) )
				{			
					$refTableClass = $arrReferenceMap[ $argStrName ]['refTableClass'];
					
					try {
						$this->$argStrName = $this->findParentRow( $refTableClass, $argStrName );
					}
					catch(Exception $objE){
						$this->$argStrName = NULL;
					}
					
					
					return $this->$argStrName;		
				}
			}
		}
		
		return parent::__get( $argStrName );
	}
	
	/**
	 * Magic getter
	 *
	 * @param unknown_type $argStrName
	 * @return unknown
	 */
	public function __set( $argStrName, $argMixVar )
	{
		if( $argMixVar === NULL )
		{
			$this->_data[ $argStrName ] = $argMixVar;
			$this->$argStrName = $argMixVar;
		}
		else if( !is_object( $argMixVar ))
		{
			parent::__set( $argStrName, $argMixVar );
		}
		else
		{
			if( array_key_exists( $argStrName, $this->_table->info('hasMany') ) )
			{
				$this->_data[ $argStrName ] = $argMixVar->toArray();
				$this->$argStrName = $argMixVar;
			}
			else
			{
				$arrReferenceMap = $this->_table->info('referenceMap');
				if( !empty( $arrReferenceMap[ $argStrName ] ) )
				{
					$this->_data[ $argStrName ] = $argMixVar->toArray();
					$this->$argStrName = $argMixVar;		
				}
			}
		}
	}
	
	/**
	 * Returns the column/value data as an array.
	 *
	 * @param array $argArrColumns
	 * @return array
	 */
    public function toArray( $argArrColumns = NULL )
    {
    	if( $argArrColumns === NULL )
    	{
    		return $this->_data;
    	}
    	else 
    	{
    		$arrData = array();
    		foreach ( $argArrColumns as $strColumnName )
    		{
    			$arrData[ $strColumnName ] = $this->_data[ $strColumnName ];
    		}
			
    		return $arrData;
    	}
    }
	
		
	/**
	 * Returns the column/value data as json.
	 *
	 * @param array $argArrColumns
	 * @return string json
	 */
    public function toJson( $argArrColumns = NULL )
    {
    	if( $argArrColumns === NULL )
    	{
    		return Zend_Json::encode( $this->_data );
    	}
    	else 
    	{
    		$arrData = array();
    		foreach ( $argArrColumns as $strColumnName )
    		{
    			$arrData[ $strColumnName ] = $this->_data[ $strColumnName ];
    		}
			
    		return Zend_Json::encode( $arrData );
    	}
    }

	
	public function getTableClassName()
	{
		return $this->_tableClass ;
	}
	
	public function getTableClass ()
	{
		return $this->_table;
	}


	/**
	 * Enter description here...
	 *
	 * @param array $argArrData
	 * @return $this
	 */
	public function setFromArray( array $argArrData, $blnColumnCheck = TRUE )
	{
		$arrTableCols = $this->_table->info('cols');
		
		foreach( $argArrData as $strColumnName => $strColumnValue )
		{
			
			if( !$blnColumnCheck || in_array( $strColumnName ,$arrTableCols) )
			{
				$this->__set( $strColumnName, $strColumnValue );
			}
		}
		
		
		return $this;
	}

	/**
	 * Enter description here...
	 *
	 * @param string $argStrGroup
	 * @param array $argArrData
	 * @return string // formated xml
	 */
	public function toXml( $argStrGroup = 'row', $argArrData = false )
	{
    	$arr = $argArrData;
    	$strXml = ''; // '<' . $argStrGroup . '>';
    	
    	if( !$argArrData )
    	{
    		$arr = $this->toArray();
    	}
    	
    	
    	if( count( $arr ) > 0 )
    	{
	    	foreach ( (array) $arr as $key => $value )
	    	{
	    		if( is_array($value) )
	    		{
	    			if( count( $value ) > 0)
	    			{
	    				if( strlen($key)<2 ) $key = 'row';
	    				$strXml .= $this->toXml($key,$value);
	    			}
	    		}
	    		else 
	    		{
	    			
	    			$strXml .= '<' . $key . '><![CDATA[' . $value . ']]></' . $key . '>';
	    		}
	    	}
    	}
        
    	$strXml .= ''; // '</' . $argStrGroup . '>';
    	
    	
    	return $strXml;
    }

    /**
     * Checks if record is already linked to a table record
     */
	public function isTableRecord()
	{
		$strPrimary = current( (array) $this->_primary );
		return ( (int) $this->_data[$strPrimary] > 0 );
	}
}